part of 'index.dart';

enum CallType {
  call, // 拨打方
  receive; // 接收方
}

class CallPage extends StatefulWidget {
  const CallPage({
    super.key,
    required this.type,
    this.from,
    this.to,
    this.channelId,
  });

  final CallType type;
  final String? from; // 电话发起方的imId
  final String? to; // 电话接收方的imId(拨打方需要，接收方不需要)
  // 如果是拨打方不需要传递channelId，如果是接听方需要使用服务端下发的channelId
  final String? channelId;

  @override
  State<CallPage> createState() => _CallPageState();
}

class _CallPageState extends State<CallPage> {
  bool initiate = false;
  bool get isCall => widget.type == CallType.call;
  Timer? _autoHangupTimer;
  bool received = false;
  bool _connecting = false;

  @override
  void initState() {
    super.initState();
    _messageListener();
    AgManager.of.init(
      onSuccess: () {
        initiate = true;
        if (isCall) {
          _onJoin();
          _startAutoHangupTimer();
        }
        AgManager.of.engine.registerEventHandler(_eventHandler());
      },
      onError: () {
        EasyLoading.showToast(T.current.c_call_fail);
        Navigator.of(context).pop();
      },
    );
  }

  RtcEngineEventHandler _eventHandler() {
    return RtcEngineEventHandler(
      // 成功加入频道回调
      onJoinChannelSuccess: (RtcConnection connection, int elapsed) {
        debugPrint(
            "==声网call==:成功加入频道回调local user ${connection.localUid} joined");
      },
      // 远端用户或主播加入当前频道回调
      onUserJoined: (RtcConnection connection, int remoteUid, int elapsed) {
        debugPrint("==声网call==:远端用户或主播加入当前频道回调remote user $remoteUid joined");
        _autoHangupTimer?.cancel();
      },
      // 远端用户或主播离开当前频道回调
      onUserOffline: (
        RtcConnection connection,
        int remoteUid,
        UserOfflineReasonType reason,
      ) {
        //if (mounted) Navigator.of(context).pop();
        debugPrint(
            "==声网call==:远端用户或主播离开当前频道回调remote user $remoteUid left channel");
      },
    );
  }

  void _messageListener() {
    EMClient.getInstance.chatManager.addEventHandler(
      "call_receive_message_listener",
      EMChatEventHandler(
        onCmdMessagesReceived: (messages) {
          for (var msg in messages) {
            if (MessageType.CMD == msg.body.type) {
              final cmdBody = msg.body as EMCmdMessageBody;
              if (cmdBody.action.isNotEmpty) {
                final map = jsonDecode(cmdBody.action);
                final event = map['event'];
                if (event == CustomMessageType.callUP.value) {
                  if (mounted) Navigator.of(context).pop();
                }
                if (event == CustomMessageType.receiveUP.value) {
                  if (mounted) Navigator.of(context).pop();
                }
              }
            }
          }
        },
      ),
    );
  }

  @override
  void dispose() {
    EMClient.getInstance.chatManager.removeMessageEvent(
      "call_receive_message_listener",
    );
    AgManager.of.engine.unregisterEventHandler(_eventHandler());
    _autoHangupTimer?.cancel();
    AgManager.of.leaveChannel();
    super.dispose();
  }

  // 自动挂断计时器
  void _startAutoHangupTimer() {
    _autoHangupTimer = Timer(const Duration(seconds: 30), () {
      if (mounted) {
        EasyLoading.showToast(T.current.c_not_answered);
        Navigator.of(context).pop();
      }
    });
  }

  // 拨打方
  void _onJoin() async {
    if (widget.to == null) return;
    final imId = UserManager.instance.currentUser?.imId;
    final channelId = imId.toString();
    final ticket = await ImAPI.rtcToken(channelId);
    if (ticket == null) {
      EasyLoading.showToast(T.current.c_call_fail);
      if (mounted) Navigator.of(context).pop();
      return;
    }
    final token = ticket.rtcToken;
    final uid = ticket.agoraUserId;
    if (token == null || uid == null) {
      EasyLoading.showToast(T.current.c_call_fail);
      if (mounted) Navigator.of(context).pop();
      return;
    }
    final result = await AgManager.of.joinChannel(
      token: token,
      uid: uid,
      channelId: channelId,
    );
    if (result) {
      ImManager.of.sendCallMessage(
        targetId: widget.to!,
        event: CustomMessageType.call.value,
        channelId: channelId,
        from: widget.from,
        to: widget.to,
      );
      AgManager.of.remoteStream.listen((value) {
        if (!value) {
          if (mounted) Navigator.of(context).pop();
        }
      });
    } else {
      EasyLoading.showToast(T.current.c_call_fail);
      if (mounted) Navigator.of(context).pop();
    }
  }

  // 接听方
  void _onRecieve() async {
    setState(() {
      _connecting = true;
    });

    _autoHangupTimer?.cancel();
    final channelId = widget.channelId;
    if (channelId == null) {
      EasyLoading.showToast(T.current.c_call_fail);
      if (mounted) Navigator.of(context).pop();
      return;
    }

    // 获取token和加入频道的逻辑
    final ticket = await ImAPI.rtcToken(channelId);
    if (ticket == null) {
      EasyLoading.showToast(T.current.c_call_fail);
      if (mounted) Navigator.of(context).pop();
      return;
    }

    final token = ticket.rtcToken;
    final uid = ticket.agoraUserId;
    if (token == null || uid == null) {
      EasyLoading.showToast(T.current.c_call_fail);
      if (mounted) Navigator.of(context).pop();
      return;
    }

    final result = await AgManager.of.joinChannel(
      token: token,
      uid: uid,
      channelId: channelId,
    );

    if (result) {
      Future.delayed(const Duration(seconds: 3), () {
        if (mounted) {
          setState(() {
            _connecting = false;
            received = true;
          });
        }
      });

      AgManager.of.remoteStream.listen((value) {
        if (!value) {
          if (mounted) Navigator.of(context).pop();
        }
      });
    } else {
      EasyLoading.showToast(T.current.c_call_fail);
      if (mounted) Navigator.of(context).pop();
    }
  }

  void _onHangup() async {
    if (widget.type == CallType.call) {
      await ImManager.of.sendCallMessage(
        targetId: widget.to!,
        event: CustomMessageType.callUP.value,
        from: widget.from,
        to: widget.to,
      );
      // await ImManager.of.sendCallUpMessage(
      //   targetId: widget.to!,
      //   event: CustomMessageType.callUP.value,
      //   from: widget.from,
      //   to: widget.to,
      // );
      if (mounted) Navigator.of(context).pop();
    }
    if (widget.type == CallType.receive) {
      await ImManager.of.sendCallMessage(
        targetId: widget.from!,
        event: CustomMessageType.receiveUP.value,
        from: widget.from,
        to: widget.to,
      );
      if (mounted) Navigator.of(context).pop();
    }
  }

  String _avatar(String? url) {
    if (url == null || url.isEmpty) {
      return Constants.avatar;
    }
    return url;
  }

  @override
  Widget build(BuildContext context) {
    final infoId = widget.type == CallType.call ? widget.to : widget.from;

    return Scaffold(
      backgroundColor: const Color(0xFF09101D),
      body: BuildLayout(
        infoChild: FutureBuilder(
          future: ImManager.of.fetchUserInfoById(infoId!),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  image(
                    _avatar(snapshot.data?.avatarUrl),
                    width: 100,
                    height: 100,
                    fit: BoxFit.cover,
                  ).clipRRect(99),
                  SizedBox(height: 20.w),
                  DefaultTextStyle.merge(
                    maxLines: 1,
                    overflow: TextOverflow.ellipsis,
                    style: TextStyle(
                      fontSize: 26.w,
                      fontWeight: FontWeight.w600,
                      color: Colors.white,
                    ),
                    child: Text(snapshot.data?.nickName ?? ''),
                  ),
                  SizedBox(height: 10.w),
                ],
              );
            }
            return const SizedBox();
          },
        ),
        operateChild: Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            // 根据状态显示不同的接听按钮
            if (!isCall && !received)
              if (_connecting)
                // 连接中状态显示带加载指示器的按钮
                IconButton(
                  Icons.call,
                  color: Colors.green,
                  onTap: () {}, // 连接中不允许再次点击
                  child: Transform.scale(
                    scale: 1,
                    child: const CircularProgressIndicator.adaptive(),
                  ),
                )
              else
                // 初始状态显示普通接听按钮
                IconButton(
                  Icons.call,
                  color: Colors.green,
                  onTap: () => _onRecieve(),
                ),

            // 挂断按钮保持不变
            IconButton(
              Icons.call_end,
              color: Colors.red,
              onTap: _onHangup,
            ),
          ],
        ),
      ),
    );
  }
}
